#pragma once
#include <list>
#include <string>
#include <map>
#include <vector>
#include <exception>
#include <memory>
using namespace std;
namespace Core
{
	struct Position
	{
		int x,y;
		Position(int X,int Y):x(X),y(Y){}
		Position(){};
		void Set(int X,int Y){x = X;y = Y;}
		/*operator POINT()
		{
		POINT p={x,y};
		return p;
		}*/

	};
	inline bool operator==(const Position& p1,const Position& p2)
	{
		return p1.x==p2.x && p1.y==p2.y;
	}
	inline bool operator!=(const Position& p1,const Position& p2)
	{
		return !(p1==p2);
	}
	struct Size
	{
		int width,height;
		Size(int Width,int Height):width(Width),height(Height){}
		int GetArea(){return width*height;}
		Size(){};
	};

	inline bool IsInRange(const Position& point, const Position& pos, const Size& size)
	{//Check whether the point is in pos+size range
		if(point.x >= pos.x && point.x <= pos.x+size.width && point.y>=pos.y && point.y<=pos.y+size.height)
		{
			return true;
		}
		else
			return false;

	}

	class WayPoint
	{
	public:
		//actually it is operator> which can give a minimal heap
		template<class Evaluator,int CostPercent>
		class  HeapLessThen
		{
			Evaluator& mEvaluator;
			double mScaleToCost;
		public:
			HeapLessThen(Evaluator& evaluator):mScaleToCost(CostPercent/100.0),mEvaluator(evaluator)
			{}
			bool operator()(const WayPoint* left, const WayPoint* right)
			{
				return ((left->cost-right->cost)*mScaleToCost+(mEvaluator(*left)-mEvaluator(*right))) > 0;
			}
		};

		double cost;
		Core::Position pos;
		WayPoint* parent;
		bool isClosed;
		WayPoint(Core::Position& Pos,double Cost,WayPoint* Parent)
			:pos(Pos),cost(Cost),parent(Parent),isClosed(false)
		{}
		WayPoint():cost(0),parent(0),isClosed(false)
		{}
	};

	std::ostream& operator<<(std::ostream& out,const WayPoint& p);
	class Null{};

	struct Zoom
	{
		float zx;
		float zy;
	};

	struct Rect
	{
		int left;
		int top;
		int right;
		int bottom;
		Rect(void);
		Rect(int iLeft, int iTop, int iRight, int iBottom);
		bool ClipRect(const Rect& range, Rect& dest,Zoom* pZoom = 0);
		void SetRect(int iLeft, int iTop, int iRight, int iBottom);
	};
}
